package com.ms.service.module.broadcastlistener;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import redis.clients.jedis.Jedis;

import com.ms.service.db.jedis.JedisManager;
import com.ms.service.module.account.message.SCharacterLoginNotify;
import com.ms.service.module.account.message.SSessionCloseNotify;
import com.xpec.c4.message.MessageTypes;
import com.xpec.c4.service.group.transportlayer.GroupMessage;
import com.xpec.c4.service.message.MessageAction;
import com.xpec.c4.service.module.ModuleName;
import com.xpec.c4.service.module.task.TaskAsyncCommand;

public class BroadcastLoginLogoutAsync extends TaskAsyncCommand {

	private static final Log log = LogFactory.getLog(BroadcastLoginLogoutAsync.class);
	
	private String redisKeys;
	
	private boolean isDeleteAfterFinish = false;

	private int messageType;
	
	private Object broadcast;
	
	@Override
	public void asyncExecute() throws Exception {
		if(broadcast == null){
			if(log.isErrorEnabled()){
				log.error("message content is null!");
			}
			return;
		}
		
		//用switch檢查一下是否合理的messageType跟消息內容
		switch (messageType) {
			case MessageTypes.S_ACCOUNT_CHARACTER_LOGIN_NOTIFY:{
				if(!(broadcast instanceof SCharacterLoginNotify)){
					if(log.isErrorEnabled()){
						log.error("messageType:"+messageType+" content is wrong class: "+broadcast.getClass().getSimpleName());
					}
					return;
				}
				else{
					if(log.isInfoEnabled()){
						//顯示一下傳遞消息的內容
						SCharacterLoginNotify notify = (SCharacterLoginNotify) broadcast;
						String sessionID = (notify.getSessionId() == null) ? null : notify.getSessionId().toString();
						String accountID = (notify.getAccountId() == null) ? null : notify.getAccountId().toString();
						String playerGUID = (notify.getPlayerId() == null) ? null : notify.getPlayerId().toString();
						String playerName = (notify.getPlayerName() == null) ? null : notify.getPlayerName().toString();
						log.info("messageType:"+messageType+", sessionID:"+sessionID+", accountID:"+accountID+", playerGUID:"+playerGUID+", playerName:"+playerName);
					}
				}
				
				break;
			}
			case MessageTypes.S_SESSION_CLOSE_NOTIFY:{
				if(!(broadcast instanceof SSessionCloseNotify)){
					if(log.isErrorEnabled()){
						log.error("messageType:"+messageType+" content is wrong class: "+broadcast.getClass().getSimpleName());
					}
					return;
				}
				else{
					if(log.isInfoEnabled()){
						//顯示一下傳遞消息的內容
						SSessionCloseNotify notify = (SSessionCloseNotify) broadcast;
						String closeType = (notify.getCloseType() == null) ? null : notify.getCloseType().name();
						String sessionID = (notify.getSessionId() == null) ? null : notify.getSessionId().toString();
						String accountID = (notify.getAccountId() == null) ? null : notify.getAccountId().toString();
						String playerGUID = (notify.getPlayerId() == null) ? null : notify.getPlayerId().toString();
						String playerName = (notify.getPlayerName() == null) ? null : notify.getPlayerName().toString();
						log.info("messageType:"+messageType+", closeType:"+closeType+", sessionID:"+sessionID+", accountID:"+accountID+", playerGUID:"+playerGUID+", playerName:"+playerName);
					}
				}
				
				break;
			}	
	
			//其他的消息不受理
			default:{
				if(log.isErrorEnabled()){
					log.error("can't send other messageType in this async, wrong messageType:"+messageType);
				}
				return;
			}
		}
		
		//取得所有的結果
		List<String> modules = getRedisResults(redisKeys.split(LoginLogoutListener.MULTI_KEY_SPLITER), isDeleteAfterFinish);

		//紀錄成功送出的modules
		ArrayList<String> completeModules = new ArrayList<String>();
		
		//對該KEY每一個module送消息
		if(modules.size() > 0){
			for(String moduleID : modules){
				GroupMessage message = new GroupMessage();
				message.setDestModuleID(moduleID);
				message.setMessageType(messageType);
				message.setMessageContent(broadcast);
				
				//嘗試對module送消息
				try {
					MessageAction.sendMessage(message);
					
					completeModules.add(moduleID);
				} catch (Exception e) {
					if(log.isErrorEnabled()){
						log.error("something wrong at send message to " + moduleID, e);
					}
					//繼續送給下一個module
					continue;
				}
			}
			
			//印出這次廣播結果
			if(log.isInfoEnabled()){
				log.info("broadcast destModules: "+modules.toString()+", complete modules:" + completeModules.toString());
			}
		}
		
	}

	@Override
	public void execute() throws Exception {
		
	}
	
	public void setRedisKeys(String redisKeys){
		this.redisKeys = redisKeys;
	}
	
	public void setDeleteAfterFinish(boolean isDeleteAfterFinish){
		this.isDeleteAfterFinish = isDeleteAfterFinish;
	}
	
	public void setMessageType(int messageType) {
		this.messageType = messageType;
	}

	public void setBroadcast(Object broadcast) {
		this.broadcast = broadcast;
	}
	
	/**
	 * 取得redis多個key的資訊
	 */
	private static List<String> getRedisResults(String[] redisKeys, boolean isDeleteAfterGet){
		if(redisKeys == null || redisKeys.length == 0)
			return null;
		
		ArrayList<String> result = new ArrayList<String>();
		
		Jedis jedis = JedisManager.getResource(ModuleName.LOGIN);
		for(String redisKey : redisKeys){
			List<String> singleResult = jedis.lrange(redisKey, 0, -1);
			
			if(singleResult.size() > 0){
				result.addAll(singleResult);
			}
			else{
				//沒有需要廣播的對象
				if(log.isWarnEnabled()){
					log.warn("redisKey:"+redisKey+", broadcast destModules is empty");
				}
			}
			
			//取得後刪除
			if(isDeleteAfterGet){
				jedis.del(redisKey);
			}
		}

		JedisManager.returnResource(ModuleName.LOGIN, jedis);
		
		return result;
	}

}
